grammar SQL;

@header {
package pucco.db;
}

@parser::members {
    @Override
    public void reportError(RecognitionException e) {
        System.out.println("CUSTOM ERROR...\n" + e);
    }
}

// ---------------------------------------------------------------------
// Basic Definitions of Characters Used, Tokens, Symbols, Etc.
// ---------------------------------------------------------------------

sql_terminal_character
	:	sql_language_character
	|	sql_embedded_language_character
	;

sql_language_character
	:	simple_latin_letter
	|	DIGIT
	|	sql_special_character
	;

simple_latin_letter
	:	SIMPLE_LATIN_UPPER_CASE_LETTER
	|	SIMPLE_LATIN_LOWER_CASE_LETTER
	;

SIMPLE_LATIN_UPPER_CASE_LETTER
	:	'A'..'Z'
	;

SIMPLE_LATIN_LOWER_CASE_LETTER
	:	'a'..'z'
	;

DIGIT
	:	'0'..'9'
	;

sql_special_character
	:	SPACE
	|	DOUBLE_QUOTE
	|	PERCENT
	|	AMPERSAND
	|	QUOTE
	|	LEFT_PAREN
	|	RIGHT_PAREN
	|	ASTERISK
	|	PLUS_SIGN
	|	COMMA
	|	MINUS_SIGN
	|	PERIOD
	|	SOLIDUS
	|	COLON
	|	SEMICOLON
	|	LESS_THAN_OPERATOR
	|	GREATER_THAN_OPERATOR
	|	EQUALS_OPERATOR
	|	QUESTION_MARK
	|	UNDERSCORE
	|	VERTICAL_BAR
	;

SPACE
	:	' '|'\t'|'\u000C'|'\n'
	;

DOUBLE_QUOTE:          '"';
PERCENT:               '%';
AMPERSAND:             '&';
QUOTE:                 '\'';
LEFT_PAREN:            '(';
RIGHT_PAREN:           ')';
ASTERISK:              '*';
PLUS_SIGN:             '+';
COMMA:                 ',';
MINUS_SIGN:            '-';
PERIOD:                '.';
SOLIDUS:               '/';
COLON:                 ':';
SEMICOLON:             ';';
LESS_THAN_OPERATOR:    '<';
EQUALS_OPERATOR:       '=';
GREATER_THAN_OPERATOR: '>';
QUESTION_MARK:         '?';
UNDERSCORE:            '_';
VERTICAL_BAR:          '|';

sql_embedded_language_character
	:	LEFT_BRACKET | RIGHT_BRACKET
	;

LEFT_BRACKET:  '[';
RIGHT_BRACKET: ']';

token
	:	nondelimiter_token
	|	delimiter_token
	;

nondelimiter_token
	:	regular_identifier
	|	key_word
	|	unsigned_numeric_literal
	|	national_character_string_literal
	|	bit_string_literal
	|	hex_string_literal
	;

regular_identifier
	:	identifier_body
	;

identifier_body
	:	identifier_start UNDERSCORE

// ---------------------------------------------------------------------
// Literal Numbers, Strings, Dates and Times
// ---------------------------------------------------------------------

unsigned_numeric_literal
	:	exect_numeric_literal
	|	approximate_numeric_literal
	;

exact_numeric_literal
	:	unsigned_integer (PERIOD unsigned_integer?)?
	|	PERIOD unsigned_integer
	;

unsigned_integer
	:	DIGIT+;

approximate_numeric_literal
	:	mantissa E exponent
	;

mantissa:	exact_numeric_literal
	;

exponent:	signed_integer
	;

signed_integer
	:	sign? unsigned_integer
	;

sign
	:	PLUS_SIGN | MINUS_SIGN
	;

national_character_string_literal
	:	N QUOTE CharacterRepresentation* QUOTE ( separator+ QUOTE CharacterRepresentation* QUOTE )*
	;

character_representation
	:	NONQUOTE_CHARACTER | quote_symbol
	;

quote_symbol
	:	QUOTE QUOTE
	;

separator
	:	(Comment Newline | Space | Newline)+
	;

Comment: '--' ~('\n'|'\r')*       {$channel=HIDDEN;};
Newline: '\r'? '\n'               {$channel=HIDDEN;};

bit_string_literal
	:	B QUOTE BIT* QUOTE ( separator+ QUOTE BIT* QUOTE )*
	;

fragment BIT: '0' | '1';

hex_string_literal
	:	X QUOTE HEXIT* QUOTE ( separator+ QUOTE HEXIT* QUOTE )*
	;

fragment HEXIT:	 DIGIT | 'A'..'F' | 'a'..'f';

delimiter_token
	:	character_string_literal
	|	date_string
	|	time_string
	|	timestamp_string
	|	delimited_identifier
	|	SQL_special_character
	|	not_equals_operator
	|	greater_than_or_equals_operator
	|	less_than_or_equals_operator
	|	concatenation_operator
	|	double_period
	|	left_bracket
	|	right_bracket
	;

schema_name
	:	Identifier
	;

// ---------------------------------------------------------------------
// SQL Module
// ---------------------------------------------------------------------

column_name
	:	Identifier
	;

// ---------------------------------------------------------------------
// Data Types
// ---------------------------------------------------------------------

data_type
	:	character_string_type (CHARACTER SET character_set_name)?
	|	national_character_string_type
	|	bit_string_type
	|	numeric_type
	|	datetime_type
	|	interval_type
	;

character_string_type
	:	character_string_type_name (LEFT_PAREN length RIGHT_PAREN)?
	;

character_string_type_name
	:	CHARACTER | CHAR | CHARACTER VARYING | CHAR VARYING | VARCHAR | VARCHAR2
	;

length
	:	unsigned_integer
	;

national_character_string_type
	:	national_character_string_type_name (LEFT_PAREN length RIGHT_PAREN)?
	;

national_character_string_type_name
	:	NATIONAL CHARACTER
	|	NATIONAL CHAR
	|	NCHAR
	|	NATIONAL CHARACTER VARYING
	|	NATIONAL CHAR VARYING
	|	NCHAR VARYING
	;

bit_string_type
	:	bit_string_type_name (LEFT_PAREN length RIGHT_PAREN)?
	;

bit_string_type_name
	:	BIT | BIT VARYING
	;

numeric_type
	:	exact_numeric_type
	|	approximate_numeric_type
	;

exact_numeric_type
	:	NUMERIC (LEFT_PAREN precision (COMMA scale)? RIGHT_PAREN)?
	|	DECIMAL (LEFT_PAREN precision (COMMA scale)? RIGHT_PAREN)?
	|	DEC (LEFT_PAREN precision (COMMA scale)? RIGHT_PAREN)?
	|	INTEGER | INT | SMALLINT
	;

precision
	:	unsigned_integer
	;

scale
	:	unsigned_integer
	;

approximate_numeric_type
	:	FLOAT (LEFT_PAREN precision RIGHT_PAREN)?
	|	REAL | DOUBLE PRECISION
	;

datetime_type
	:	DATE
	|	TIME (LEFT_PAREN time_precision RIGHT_PAREN)? (WITH TIME ZONE)?
	|	TIMESTAMP (LEFT_PAREN timestamp_precision RIGHT_PAREN)? (WITH TIME ZONE)?
	;

time_precision
	:	time_fractional_seconds_precision
	;

time_fractional_seconds_precision
	:	unsigned_integer
	;

timestamp_precision
	:	time_fractional_seconds_precision
	;

interval_type
	:	INTERVAL interval_qualifier
	;

interval_qualifier
	:	start_field TO end_field
	|	single_datetime_field
	;

start_field
	:	non_second_datetime_field (LEFT_PAREN interval_leading_field_precision RIGHT_PAREN)?
	;

non_second_datetime_field
	:	YEAR | MONTH | DAY | HOUR | MINUTE
	;

interval_leading_field_precision
	:	unsigned_integer
	;

end_field
	:	non_second_datetime_field
	|	SECOND (LEFT_PAREN interval_fractional_seconds_precision RIGHT_PAREN)?
	;

interval_fractional_seconds_precision
	:	unsigned_integer
	;

single_datetime_field
	:	non_second_datetime_field (LEFT_PAREN interval_leading_field_precision RIGHT_PAREN)?
	|	SECOND (LEFT_PAREN interval_leading_field_precision (COMMA LEFT_PAREN interval_fractional_seconds_precision)? RIGHT_PAREN)?
	;

domain_name
	:	qualified_name
	;

qualified_name
	:	(schema_name PERIOD)? qualified_identifier
	;

default_clause
	:	DEFAULT default_option
	;

default_option
	:	literal
	|	datetime_value_function
	|	USER
	|	CURRENT_USER
	|	SESSION_USER
	|	SYSTEM_USER
	|	NULL
	;

// ---------------------------------------------------------------------
// Literals
// ---------------------------------------------------------------------

literal
	:	signed_numeric_literal | general_literal
	;

signed_numeric_literal
	:	sign? unsigned_numeric_literal
	;

general_literal
	:	character_string_literal
	|	national_character_string_literal
	|	bit_string_literal
	|	hex_string_literal
	|	datetime_literal
	|	interval_literal
	;

datetime_literal
	:	date_literal | time_literal | timestamp_literal
	;

date_literal
	:	DATE date_string
	;

time_literal
	:	TIME time_string
	;

timestamp_literal
	:	TIMESTAMP timestamp_string
	;

interval_literal
	:	INTERVAL sign? interval_string interval_qualifier
	;

datetime_value_function
	:	current_date_value_function
	|	current_time_value_function
	|	current_timestamp_value_function
	;

current_date_value_function
	:	CURRENT_DATE
	;

current_time_value_function
	:	CURRENT_TIME (LEFT_PAREN time_precision RIGHT_PAREN)?
	;

current_timestamp_value_function
	:	CURRENT_TIMESTAMP (LEFT_PAREN timestamp_precision RIGHT_PAREN)?
	;

// ---------------------------------------------------------------------
// Constraints
// ---------------------------------------------------------------------

column_constraint_definition
	:	constraint_name_definition? column_constraint constraint_attributes?
	;

constraint_name_definition
	:	CONSTRAINT constraint_name
	;

constraint_name
	:	qualified_name
	;

column_constraint
	:	NOT NULL
	|	unique_specification
	|	reference_specification
	|	check_constraint_definition
	;

unique_specification
	:	UNIQUE | PRIMARY KEY
	;

reference_specification
	:	REFERENCES referenced_table_and_column (MATCH match_type)? referential_triggered_action?
	;

referenced_table_and_column
	:	table_name (LEFT_PAREN reference_column_list RIGHT_PAREN)
	;

table_name 
	:	qualified_name | qualified_local_table_name
	;

reference_column_list
	:	column_name_list
	;

column_name_list
	:	column_name (COMMA column_name)*
	;

match_type
	:	FULL | PARTIAL
	;

referential_triggered_action
	:	update_rule delete_rule?
	|	delete_rule update_rule?
	;

update_rule
	:	ON UPDATE referential_action
	;

referential_action
	:	CASCADE | SET NULL | SET DEFAULT | NO ACTION
	;

delete_rule
	:	ON DELETE referential_action
	;

check_constraint_definition
	:	CHECK LEFT_PAREN search_condition RIGHT_PAREN
	;

// ---------------------------------------------------------------------
// Search Condition
// ---------------------------------------------------------------------

search_condition
	:	boolean_term
	|	boolean_term OR search_condition
	;

boolean_term
	:	boolean_factor
	|	boolean_factor AND boolean_term
	;

boolean_factor
	:	NOT? boolean_test
	;

boolean_test
	:	boolean_primary (IS NOT? truth_value)?
	;

boolean_primary
	:	predicate | LEFT_PAREN search_condition RIGHT_PAREN
	;

predicate
	:	comparison_predicate
	|	between_predicate
	|	in_predicate
	|	like_predicate
	|	null_predicate
	|	quantified_comparison_predicate
	|	exists_predicate
	|	match_predicate
	|	overlaps_predicate
	;

comparison_predicate
	:	row_value_constructor comp_op row_value_constructor
	;

row_value_constructor
	:	row_value_constructor_element
	|	LEFT_PAREN row_value_constructor_list RIGHT_PAREN
	|	row_subquery
	;

row_value_constructor_element
	:	value_expression
	|	null_specification
	|	default_specification
	;

value_expression
	:	numeric_value_expression
	|	string_value_expression
	|	datetime_value_expression
	|	interval_value_expression
	;

numeric_value_expression
	:	term
	|	term PLUS_SIGN numeric_value_expression
	|	term MINUS_SIGN numeric_value_expression
	;

term
	:	factor
	|	factor ASTERISK term
	|	factor SOLIDUS term
	;

factor
	:	sign? numeric_primary
	;

numeric_primary
	:	value_expression_primary | numeric_value_function
	;

value_expression_primary
	:	unsigned_value_specification
	|	column_reference
	|	set_function_specification
	|	scalar_subquery
	|	case_expression
	|	LEFT_PAREN <value expression> RIGHT_PAREN
	|	<cast specification> 
	;

unsigned_value_specification
	:	unsigned_literal | general_value_specification
	;

unsigned_literal
	:	unsigned_numeric_literal | general_literal
	; 

general_value_specification
	:	USER | CURRENT_USER | SESSION_USER | SYSTEM_USER | VALUE
//	|	parameter_specification
//	|	dynamic_parameter_specification
//	|	variable_specification
	;

column_reference
	:	(qualifier PERIOD)? column_name

qualifier
	:	table_name | correlation_name
	; 

correlation_name
	:	identifier
	;

set_function_specification
	:	COUNT  LEFT_PAREN ASTERISK RIGHT_PAREN
	|	general_set_function
	;

general_set_function
	:	set_function_type LEFT_PAREN set_quantifier? value_expression RIGHT_PAREN
	;

set_function_type
	:	AVG
	|	MAX
	|	MIN
	|	SUM
	|	COUNT
	;

set_quantifier
	:	DISTINCT
	|	ALL
	;

// ---------------------------------------------------------------------
// Queries
// ---------------------------------------------------------------------

scalar_subquery
	:	subquery
	;

subquery
	:	LEFT_PAREN query_expression RIGHT_PAREN
	;

query_expression
	:	non_join_query_expression | joined_table
	;

non_join_query_term
	:	non_join_query_term
	|	query_expression UNION ALL? corresponding_spec? query_primary
	;

non_join_query_primary
	:	simple_table | LEFT_PAREN non_join_query_expression RIGHT_PAREN
	;

simple_table
	:	query_specification
	|	table_value_constructor
	|	explicit_table
	;

query_specification
	:	SELECT set_quantifier? select_list table_expression
	;

select_list
	:	ASTERISK
	|	select_sublist (COMMA select_sublist)*
	;

select_sublist
	:	derived_column | qualifier PERIOD ASTERISK
	;

derived_column
	:	value_expression as_clause?
	;

as_clause
	:	AS? column_name
	;

table_expression	
	:	from_clause where_clause? group_by_clause? having_clause?
	;

from_clause
	:	FROM table_reference (COMMA table_reference)*
	;

table_reference
	:	table_name correlation_specification?
	|	derived_table correlation_specification
	|	joined_table
	;

correlation_specification
	:	AS? correlation_name (LEFT_PAREN derived_column_list RIGHT_PAREN)?
	;

derived_column_list
	:	column_name_list
	;

derived_table
	:	table_subquery
	;

table_subquery
	:	subquery
	;

joined_table
	:	cross_join
	|	qualified_join
	|	LEFT_PAREN joined_table RIGHT_PAREN
	;

cross_join
	:	table_reference CROSS JOIN table_reference
	;

qualified_join
	:	table_reference NATURAL? join_type? JOIN table_reference join_specification?
	;

join_type
	:	INNER
	|	outer_join_type OUTER?
	|	UNION
	;

outer_join_type
	:	LEFT | RIGHT | FULL
	;

join_specification
	:	join_condition | named_columns_join
	;

join_condition
	:	ON search_condition
	;

named_columns_join
	:	USING LEFT_PAREN join_column_list RIGHT_PAREN
	;

join_column_list
	:	column_name_list
	;

where_clause
	:	WHERE search_condition
	;

group_by_clause
	:	GROUP BY grouping_column_reference_list
	;

grouping_column_reference_list
	:	grouping_column_reference (COMMA grouping_column_reference)?
	;

grouping_column_reference
	:	column_reference collate_clause?

collate_clause
	:	COLLATE collation_name
	;

collation_name
	:	qualified_name
	;

having_clause
	:	HAVING search_condition
	;

table_value_constructor
	:	VALUES table_value_constructor_list
	;

table_value_constructor_list
	:	row_value_constructor (COMMA row_value_constructor)*
	;

explicit_table
	:	TABLE table_name
	;

query_term
	:	non_join_query_term | joined_table
	;

corresponding_spec
	:	CORRESPONDING (BY LEFT_PAREN corresponding_column_list RIGHT_PAREN)?
	;

corresponding_column_list
	:	column_name_list
	;

query_primary
	:	non_join_query_primary | joined_table
	;

// ---------------------------------------------------------------------
// Query expression components
// ---------------------------------------------------------------------

case_expression
	:	case_abbreviation | case_specification
	;

case_abbreviation
	:	NULLIF LEFT_PAREN value_expression COMMA value_expression RIGHT_PAREN
	|	COALESCE LEFT_PAREN value_expression (COMMA value_expression)+ RIGHT_PAREN
	;

case_specification
	:	simple_case | searched_case
	;

simple_case
	:	CASE case_operand simple_when_clause+ else_clause? END
	;

case_operand
	:	value_expression
	;

simple_when_clause
	:	WHEN when_operand THEN result
	;

when_operand
	:	value_expression
	;

result
	:	result_expression | NULL
	;

result_expression
	:	value_expression
	;

else_clause
	:	ELSE result
	;

searched_case
	:	CASE searched_when_clause+ else_clause? END
	;

searched_when_clause
	:	WHEN search_condition THEN result
	;

cast_specification
	:	CAST LEFT_PAREN cast_operand AS cast_target RIGHT_PAREN
	;

cast_operand
	:	value_expression | NULL
	;

cast_target
	:	domain_name | data_type
	;

numeric_value_function
	:	position_expression | extract_expression | length_expression
	;

position_expression
	:	POSITION LEFT_PAREN character_value_expression IN character_value_expression RIGHT_PAREN
	;

character_value_expression
	:	concatenation | character_factor
	;

concatenation
	:	character_value_expression CONCATENATION_OPERATOR character_factor
	;

character_factor
	:	character_primary collate_clause?
	;

character_primary
	:	value_expression_primary | string_value_function
	;

string_value_function
	:	character_value_function | bit_value_function
	;

character_value_function
	:	character_substring_function
	|	fold
	|	form_of_use_conversion	
	|	character_translation
	|	trim_function
	;

character_substring_function
	:	SUBSTRING LEFT_PAREN character_value_expression FROM start_position (FOR string_length)? RIGHT_PAREN
	;

start_position
	:	numeric_value_expression
	;

string_length
	:	numeric_value_expression
	;

fold
	:	(UPPER | LOWER) LEFT_PAREN character_value_expression RIGHT_PAREN
	;

form_of_use_conversion
	:	CONVERT	LEFT_PAREN character_value_expression USING form_of_use_conversion_name RIGHT_PAREN
	;

form_of_use_conversion_name
	:	qualified_name
	;

character_translation
	:	TRANSLATE LEFT_PAREN character_value_expression USING translation_name RIGHT_PAREN
	;

translation_name
	:	qualified_name
	;

trim_function
	:	TRIM LEFT_PAREN trim_operands RIGHT_PAREN
	;

trim_operands
	:	(trim_specification? trim_character? FROM)? trim_source
	;

trim_specification
	:	LEADING | TRAILING | BOTH
	;

trim_character
	:	character_value_expression
	;

trim_source
	:	character_value_expression
	;

bit_value_function
	:	bit_substring_function
	;

bit_substring_function
	:	SUBSTRING LEFT_PAREN bit_value_expression FROM start_position (FOR string_length)? RIGHT_PAREN
	;

bit_value_expression
	:	bit_concatenation | bit_factor
	;

bit_concatenation
	:	bit_value_expression concatenation_operator bit_factor
	;

bit_factor
	:	bit_primary
	;

bit_primary
	:	value_expression_primary | string_value_function
	;

extract_expression
	:	EXTRACT LEFT_PAREN extract_field FROM extract_source RIGHT_PAREN
	;

extract_field
	:	datetime_field | time_zone_field
	;

datetime_field
	:	non_second_datetime_field | SECOND
	;

time_zone_field
	:	TIMEZONE_HOUR | TIMEZONE_MINUTE
	;

extract_source
	:	datetime_value_expression | interval_value_expression
	;

datetime_value_expression
	:	datetime_term
	|	interval_value_expression PLUS_SIGN datetime_term
	|	datetime_value_expression PLUS_SIGN interval_term
	|	datetime_value_expression MINUS_SIGN interval_term
	;

interval_term
	:	interval_factor
	|	interval_term_2 ASTERISK factor
	|	interval_term_2 SOLIDUS factor
	|	term ASTERISK interval_factor
	;

interval_factor
	:	sign? interval_primary
	;

interval_primary
	:	value_expression_primary interval_qualifier?
	;

interval_term_2
	:	interval_term
	;

interval_value_expression
	:	interval_term
	|	interval_value_expression_1 PLUS_SIGN interval_term_1
	|	interval_value_expression_1 MINUS_SIGN interval_term_1
	|	LEFT_PAREN datetime_value_expression MINUS_SIGN datetime_term RIGHT_PAREN interval_qualifier
	;

interval_expression_1
	:	interval_value_expression
	;

interval_term_1
	:	interval_term
	;

datetime_term
	:	datetime_factor
	;

datetime_factor
	:	datetime_primary time_zone?
	;

datetime_primary
	:	value_expression_primary | datetime_value_function
	;

time_zone
	:	AT time_zone_specifier
	;

time_zone_specifier
	:	LOCAL | TIME ZONE interval_value_expression
	;

length_expression
	:	char_length_expression | octet_length_expression | bit_length_expression
	;

char_length_expression
	:	(CHAR_LENGTH | CHARACTER_LEGNTH) LEFT_PAREN string_value_expression RIGHT_PAREN
	;

string_value_expression
	:	character_value_expression | bit_value_expression
	;

octet_length_expression
	:	OCTET_LENGTH LEFT_PAREN string_value_expression RIGHT_PAREN
	;

bit_length_expression
	:	BIT_LENGTH LEFT_PAREN string_value_expression RIGHT_PAREN
	;

null_specification
	:	NULL
	;

default_specification
	:	DEFAULT
	;

row_value_constructor_list
	:	row_value_constructor_element (COMMA row_value_constructor_element)*
	;

row_subquery
	:	subquery
	;

comp_op
	:	EQUALS_OPERATOR
	|	NOT_EQUALS_OPERATOR
	|	LESS_THAN_OPERATOR
	|	GREATER_THAN_OPERATOR
	|	LESS_THAN_OR_EQUALS_OPERATOR
	|	GREATER_THAN_OR_EQUALS_OPERATOR
	;

between_predicate
	:	row_value_constructor NOT? BETWEEN row_value_constructor AND row_value_constructor
	;

in_predicate
	:	row_value_constructor NOT? IN in_predicate_value
	;

in_predicate_value
	:	table_subquery | LEFT_PAREN in_value_list RIGHT_PAREN
	;

in_value_list
	:	value_expression (COMMA value_expression)+ /* min=2? */
	;

like_predicate
	:	match_value NOT? LIKE pattern (ESCAPE escape_character)?
	;

match_value
	:	character_value_expression
	;

pattern
	:	character_value_expression
	;

escape_character
	:	character_value_expression
	;

null_predicate
	:	IS NOT? NULL
	;

quantified_comparison_predicate
	:	row_value_constructor comp_op quantifier table_subquery
	;

quantifier
	:	all | some
	;

all
	:	ALL
	;

some
	:	SOME | ANY
	;

exists_predicate
	:	EXISTS table_subquery
	;

unique_predicate
	:	UNIQUE table_subquery
	;

match_predicate
	:	row_value_constructor MATCH UNIQUE? (PARTIAL | FULL)? table_subquery
	;

overlaps_predicate
	:	row_value_constructor_1 OVERLAPS row_value_constructor_2
	;

row_value_constructor_1
	:	row_value_constructor
	;

row_value_constructor_2
	:	row_value_constructor
	;

truth_value
	:	TRUE | FALSE | UNKNOWN
	;

// ---------------------------------------------------------------------
// More about constraints
// ---------------------------------------------------------------------



// ---------------------------------------------------------------------
// Module contents
// ---------------------------------------------------------------------


// ---------------------------------------------------------------------
// SQL Procedures
// ---------------------------------------------------------------------


// ---------------------------------------------------------------------
// SQL Schema Definition Statements
// ---------------------------------------------------------------------


// ---------------------------------------------------------------------
// SQL Data Manipulation Statements
// ---------------------------------------------------------------------

// ---------------------------------------------------------------------
// Connection Management
// ---------------------------------------------------------------------

// ---------------------------------------------------------------------
// Session Attributes
// ---------------------------------------------------------------------

// ---------------------------------------------------------------------
// Dynamic SQL
// ---------------------------------------------------------------------

// ---------------------------------------------------------------------
// Identifying the version of SQL in use
// ---------------------------------------------------------------------


table_definition 
	:	CREATE TABLE table_name table_element_list
	;



table_element_list
	:	LEFT_PAREN table_element (COMMA table_element)? RIGHT_PAREN
	;

table_element
	:	column_definition | table_constraint_definition
	;

column_definition
	:	column_name ( data_type | domain_name ) default_clause? column_constraint_definition+ collate_clause?
	;



character_set_name
	:	(schema_name PERIOD)? Identifier
	;




time_precision
	:	time_fractional_seconds_precision
	;

time_fractional_seconds_precision
	:	unsigned_integer
	;

timestamp_precision
	:	time_fractional_seconds_precision
	;

character_string_literal
	:	QUOTE CharacterRepresentation* QUOTE ( separator+ QUOTE CharacterRepresentation* QUOTE )*
	;




date_string
	:	QUOTE date_value QUOTE
	;

date_value
	:	years_value MINUS_SIGN months_value MINUS_SIGN days_value	
	;

years_value
	:	datetime_value
	;
months_value
	:	datetime_value
	;
days_value
	:	datetime_value
	;

datetime_value
	:	unsigned_integer
	;

time_string
	:	QUOTE time_value time_zone_interval? QUOTE
	;

time_value
	:	hours_value COLON minutes_value COLON
	;

hours_value
	:	datetime_value
	;

minutes_value
	:	datetime_value
	;

seconds_value
	:	unsigned_integer (PERIOD unsigned_integer)?
	;

time_zone_interval
	:	sign hours_value COLON minutes_value
	;

timestamp_string
	:	QUOTE date_value Space time_value time_zone_interval? QUOTE
	;


interval_string
	:	QUOTE (year_month_literal | day_time_literal) QUOTE
	;




year_month_literal
	:	years_value
	|	(years_value MINUS_SIGN)? months_value
	;

day_time_literal
	:	day_time_interval | time_interval
	;

day_time_interval
	:	days_value (Space hours_value (COLON minutes_value (COLON seconds_value)?)?)?
	;

time_interval
	:	hours_value (COLON minutes_value (COLON seconds_value)?)?
	|	minutes_value (COLON seconds_value)?
	|	seconds_value
	;






constraint_attributes
	:	constraint_check_time (NOT? DEFERRABLE)?
	|	NOT? DEFERRABLE constraint_check_time?
	;

constraint_check_time
	:	INITIALLY DEFERRED | INITIALLY IMMEDIATE
	;


qualified_identifier
	:	Identifier
	;








;
	
	
CharacterRepresentation: QUOTE (~'\'')* QUOTE;
Integer:                 MINUS_SIGN? unsigned_integer;
Identifier:              LETTER (LETTER | DIGIT | UNDERSCORE | NUMBER_SIGN | DOLLAR)*;


fragment LETTER: ('A'..'Z' | 'a'..'z');

fragment NONQUOTE_CHARACTER: ~'\'';

fragment NOT_EQUALS_OPERATOR:             LESS_THAN_OPERATOR GREATER_THAN_OPERATOR;
fragment GREATER_THAN_OR_EQUALS_OPERATOR: GREATER_THAN_OPERATOR EQUALS_OPERATOR;
fragment LESS_THAN_OR_EQUALS_OPERATOR:    LESS_THAN_OPERATOR EQUALS_OPERATOR;
fragment CONCATENATION_OPERATOR:          VERTICAL_BAR VERTICAL_BAR;

ASTERISK:              '*';
COLON:                 ':';
COMMA:                 ',';
DOLLAR:                '$';
EQUALS_OPERATOR:       '=';
GREATER_THAN_OPERATOR: '>';
LEFT_PAREN:            '(';
LESS_THAN_OPERATOR:    '<';
MINUS_SIGN:            '-';
NUMBER_SIGN:           '#';
PERIOD:                '.';
PLUS_SIGN:             '+';
QUESTION_MARK:         '?';
QUOTE:                 '\'';
RIGHT_PAREN:           ')';
SEMICOLON:             ';';
SOLIDUS:               '/';
UNDERSCORE:            '_';
VERTICAL_BAR:          '|';


// (shell-command "perl SQL_keywords.pl -d" 1)
ABSOLUTE:                    A B S O L U T E;
ACTION:                      A C T I O N;
ADA:                         A D A;
ADD:                         A D D;
ALL:                         A L L;
ALLOCATE:                    A L L O C A T E;
ALTER:                       A L T E R;
AND:                         A N D;
ANY:                         A N Y;
ARE:                         A R E;
AS:                          A S;
ASC:                         A S C;
ASSERTION:                   A S S E R T I O N;
AT:                          A T;
AUTHORIZATION:               A U T H O R I Z A T I O N;
AVG:                         A V G;
BEGIN:                       B E G I N;
BETWEEN:                     B E T W E E N;
BIT:                         B I T;
BIT_LENGTH:                  B I T UNDERSCORE L E N G T H;
BOTH:                        B O T H;
BY:                          B Y;
C:                           C;
CASCADE:                     C A S C A D E;
CASCADED:                    C A S C A D E D;
CASE:                        C A S E;
CAST:                        C A S T;
CATALOG:                     C A T A L O G;
CATALOG_NAME:                C A T A L O G UNDERSCORE N A M E;
CHAR:                        C H A R;
CHARACTER:                   C H A R A C T E R;
CHARACTER_LENGTH:            C H A R A C T E R UNDERSCORE L E N G T H;
CHARACTER_SET_CATALOG:       C H A R A C T E R UNDERSCORE S E T UNDERSCORE C A T A L O G;
CHARACTER_SET_NAME:          C H A R A C T E R UNDERSCORE S E T UNDERSCORE N A M E;
CHARACTER_SET_SCHEMA:        C H A R A C T E R UNDERSCORE S E T UNDERSCORE S C H E M A;
CHAR_LENGTH:                 C H A R UNDERSCORE L E N G T H;
CHECK:                       C H E C K;
CLASS_ORIGIN:                C L A S S UNDERSCORE O R I G I N;
CLOSE:                       C L O S E;
COALESCE:                    C O A L E S C E;
COBOL:                       C O B O L;
COLLATE:                     C O L L A T E;
COLLATION:                   C O L L A T I O N;
COLLATION_CATALOG:           C O L L A T I O N UNDERSCORE C A T A L O G;
COLLATION_NAME:              C O L L A T I O N UNDERSCORE N A M E;
COLLATION_SCHEMA:            C O L L A T I O N UNDERSCORE S C H E M A;
COLUMN:                      C O L U M N;
COLUMN_NAME:                 C O L U M N UNDERSCORE N A M E;
COMMAND_FUNCTION:            C O M M A N D UNDERSCORE F U N C T I O N;
COMMIT:                      C O M M I T;
COMMITTED:                   C O M M I T T E D;
CONDITION_NUMBER:            C O N D I T I O N UNDERSCORE N U M B E R;
CONNECT:                     C O N N E C T;
CONNECTION:                  C O N N E C T I O N;
CONNECTION_NAME:             C O N N E C T I O N UNDERSCORE N A M E;
CONSTRAINT:                  C O N S T R A I N T;
CONSTRAINTS:                 C O N S T R A I N T S;
CONSTRAINT_CATALOG:          C O N S T R A I N T UNDERSCORE C A T A L O G;
CONSTRAINT_NAME:             C O N S T R A I N T UNDERSCORE N A M E;
CONSTRAINT_SCHEMA:           C O N S T R A I N T UNDERSCORE S C H E M A;
CONSTRATIN_CATALOG:          C O N S T R A T I N UNDERSCORE C A T A L O G;
CONTINUE:                    C O N T I N U E;
CONVERT:                     C O N V E R T;
CORRESPONDING:               C O R R E S P O N D I N G;
COUNT:                       C O U N T;
CREATE:                      C R E A T E;
CROSS:                       C R O S S;
CURRENT:                     C U R R E N T;
CURRENT_DATE:                C U R R E N T UNDERSCORE D A T E;
CURRENT_TIME:                C U R R E N T UNDERSCORE T I M E;
CURRENT_TIMESTAMP:           C U R R E N T UNDERSCORE T I M E S T A M P;
CURRENT_USER:                C U R R E N T UNDERSCORE U S E R;
CURSOR:                      C U R S O R;
CURSOR_NAME:                 C U R S O R UNDERSCORE N A M E;
DATA:                        D A T A;
DATE:                        D A T E;
DATETIME_INTERVAL_CODE:      D A T E T I M E UNDERSCORE I N T E R V A L UNDERSCORE C O D E;
DATETIME_INTERVAL_PRECISION: D A T E T I M E UNDERSCORE I N T E R V A L UNDERSCORE P R E C I S I O N;
DAY:                         D A Y;
DEALLOCATE:                  D E A L L O C A T E;
DEC:                         D E C;
DECIMAL:                     D E C I M A L;
DECLARE:                     D E C L A R E;
DEFAULT:                     D E F A U L T;
DEFERRABLE:                  D E F E R R A B L E;
DEFERRED:                    D E F E R R E D;
DELETE:                      D E L E T E;
DESC:                        D E S C;
DESCRIBE:                    D E S C R I B E;
DESCRIPTOR:                  D E S C R I P T O R;
DIAGNOSTICS:                 D I A G N O S T I C S;
DISCONNECT:                  D I S C O N N E C T;
DISTINCT:                    D I S T I N C T;
DOMAIN:                      D O M A I N;
DOUBLE:                      D O U B L E;
DOUBLE_PRECISION:            D O U B L E UNDERSCORE P R E C I S I O N;
DROP:                        D R O P;
DYNAMIC_FUNCTION:            D Y N A M I C UNDERSCORE F U N C T I O N;
ELSE:                        E L S E;
END:                         E N D;
END-EXEC:                    E N D - E X E C;
ESCAPE:                      E S C A P E;
EXCEPT:                      E X C E P T;
EXCEPTION:                   E X C E P T I O N;
EXEC:                        E X E C;
EXECUTE:                     E X E C U T E;
EXISTS:                      E X I S T S;
EXTERNAL:                    E X T E R N A L;
EXTRACT:                     E X T R A C T;
FALSE:                       F A L S E;
FETCH:                       F E T C H;
FIRST:                       F I R S T;
FLOAT:                       F L O A T;
FOR:                         F O R;
FOREIGN:                     F O R E I G N;
FORTRAN:                     F O R T R A N;
FOUND:                       F O U N D;
FROM:                        F R O M;
FULL:                        F U L L;
GET:                         G E T;
GLOBAL:                      G L O B A L;
GO:                          G O;
GOTO:                        G O T O;
GRANT:                       G R A N T;
GROUP:                       G R O U P;
HAVING:                      H A V I N G;
HOUR:                        H O U R;
High:                        H i g h;
IDENTITY:                    I D E N T I T Y;
IMMEDIATE:                   I M M E D I A T E;
IN:                          I N;
INDICATOR:                   I N D I C A T O R;
INDICATOR_TYPE:              I N D I C A T O R UNDERSCORE T Y P E;
INITIALLY:                   I N I T I A L L Y;
INNER:                       I N N E R;
INPUT:                       I N P U T;
INSENSITIVE:                 I N S E N S I T I V E;
INSERT:                      I N S E R T;
INT:                         I N T;
INTEGER:                     I N T E G E R;
INTERSECT:                   I N T E R S E C T;
INTERVAL:                    I N T E R V A L;
INTO:                        I N T O;
IS:                          I S;
ISOLATION:                   I S O L A T I O N;
IntegrityNo:                 I n t e g r i t y N o;
IntegrityYes:                I n t e g r i t y Y e s;
Intermediate:                I n t e r m e d i a t e;
JOIN:                        J O I N;
KEY:                         K E Y;
LANGUAGE:                    L A N G U A G E;
LAST:                        L A S T;
LEADING:                     L E A D I N G;
LEFT:                        L E F T;
LENGTH:                      L E N G T H;
LEVEL:                       L E V E L;
LIKE:                        L I K E;
LOCAL:                       L O C A L;
LOWER:                       L O W E R;
Low:                         L o w;
MATCH:                       M A T C H;
MAX:                         M A X;
MESSAGE_LENGTH:              M E S S A G E UNDERSCORE L E N G T H;
MESSAGE_OCTET_LENGTH:        M E S S A G E UNDERSCORE O C T E T UNDERSCORE L E N G T H;
MESSAGE_TEXT:                M E S S A G E UNDERSCORE T E X T;
MIN:                         M I N;
MINUTE:                      M I N U T E;
MODULE:                      M O D U L E;
MONTH:                       M O N T H;
MORE:                        M O R E;
MUMPS:                       M U M P S;
NAME:                        N A M E;
NAMES:                       N A M E S;
NATIONAL:                    N A T I O N A L;
NATURAL:                     N A T U R A L;
NCHAR:                       N C H A R;
NEXT:                        N E X T;
NO:                          N O;
NOT:                         N O T;
NULL:                        N U L L;
NULLABLE:                    N U L L A B L E;
NULLIF:                      N U L L I F;
NUMBER:                      N U M B E R;
NUMERIC:                     N U M E R I C;
OCTET_LENGTH:                O C T E T UNDERSCORE L E N G T H;
OF:                          O F;
ON:                          O N;
ONLY:                        O N L Y;
OPEN:                        O P E N;
OPTION:                      O P T I O N;
OR:                          O R;
ORDER:                       O R D E R;
OUTER:                       O U T E R;
OUTPUT:                      O U T P U T;
OVERLAPS:                    O V E R L A P S;
PAD:                         P A D;
PARTIAL:                     P A R T I A L;
PASCAL:                      P A S C A L;
PLI:                         P L I;
POSITION:                    P O S I T I O N;
PRECISION:                   P R E C I S I O N;
PREPARE:                     P R E P A R E;
PRESERVE:                    P R E S E R V E;
PRIMARY:                     P R I M A R Y;
PRIOR:                       P R I O R;
PRIVILEGES:                  P R I V I L E G E S;
PROCEDURE:                   P R O C E D U R E;
PUBLIC:                      P U B L I C;
READ:                        R E A D;
REAL:                        R E A L;
REFERENCES:                  R E F E R E N C E S;
RELATIVE:                    R E L A T I V E;
REPEATABLE:                  R E P E A T A B L E;
RESTRICT:                    R E S T R I C T;
RETURNED_LENGTH:             R E T U R N E D UNDERSCORE L E N G T H;
RETURNED_OCTET_LENGTH:       R E T U R N E D UNDERSCORE O C T E T UNDERSCORE L E N G T H;
RETURNED_SQLSTATE:           R E T U R N E D UNDERSCORE S Q L S T A T E;
REVOKE:                      R E V O K E;
RIGHT:                       R I G H T;
ROLLBACK:                    R O L L B A C K;
ROWS:                        R O W S;
ROW_COUNT:                   R O W UNDERSCORE C O U N T;
SCALE:                       S C A L E;
SCHEMA:                      S C H E M A;
SCHEMA_NAME:                 S C H E M A UNDERSCORE N A M E;
SCROLL:                      S C R O L L;
SECOND:                      S E C O N D;
SECTION:                     S E C T I O N;
SELECT:                      S E L E C T;
SERIALIZABLE:                S E R I A L I Z A B L E;
SERVER_NAME:                 S E R V E R UNDERSCORE N A M E;
SESSION:                     S E S S I O N;
SESSION_USER:                S E S S I O N UNDERSCORE U S E R;
SET:                         S E T;
SIZE:                        S I Z E;
SMALLINT:                    S M A L L I N T;
SOME:                        S O M E;
SPACE:                       S P A C E;
SQL:                         S Q L;
SQLCODE:                     S Q L C O D E;
SQLCODE_TYPE:                S Q L C O D E UNDERSCORE T Y P E;
SQLERROR:                    S Q L E R R O R;
SQLSTATE:                    S Q L S T A T E;
SQLSTATE_TYPE:               S Q L S T A T E UNDERSCORE T Y P E;
SQL_STANDARD:                S Q L UNDERSCORE S T A N D A R D;
SUBCLASS_ORIGIN:             S U B C L A S S UNDERSCORE O R I G I N;
SUBSTRING:                   S U B S T R I N G;
SUM:                         S U M;
SYSTEM_USER:                 S Y S T E M UNDERSCORE U S E R;
TABLE:                       T A B L E;
TABLE_NAME:                  T A B L E UNDERSCORE N A M E;
TEMPORARY:                   T E M P O R A R Y;
THEN:                        T H E N;
TIME:                        T I M E;
TIMESTAMP:                   T I M E S T A M P;
TIMEZONE_HOUR:               T I M E Z O N E UNDERSCORE H O U R;
TIMEZONE_MINUTE:             T I M E Z O N E UNDERSCORE M I N U T E;
TO:                          T O;
TRAILING:                    T R A I L I N G;
TRANSACTION:                 T R A N S A C T I O N;
TRANSLATE:                   T R A N S L A T E;
TRANSLATION:                 T R A N S L A T I O N;
TRIM:                        T R I M;
TRUE:                        T R U E;
TYPE:                        T Y P E;
UNCOMMITTED:                 U N C O M M I T T E D;
UNION:                       U N I O N;
UNIQUE:                      U N I Q U E;
UNKNOWN:                     U N K N O W N;
UNNAMED:                     U N N A M E D;
UPDATE:                      U P D A T E;
UPPER:                       U P P E R;
USAGE:                       U S A G E;
USER:                        U S E R;
USING:                       U S I N G;
VALUE:                       V A L U E;
VALUES:                      V A L U E S;
VARCHAR:                     V A R C H A R;
VARYING:                     V A R Y I N G;
VIEW:                        V I E W;
WHEN:                        W H E N;
WHENEVER:                    W H E N E V E R;
WHERE:                       W H E R E;
WITH:                        W I T H;
WORK:                        W O R K;
WRITE:                       W R I T E;
YEAR:                        Y E A R;
ZONE:                        Z O N E;
fragment A: ('a' | 'A');
fragment B: ('b' | 'B');
fragment C: ('c' | 'C');
fragment D: ('d' | 'D');
fragment E: ('e' | 'E');
fragment F: ('f' | 'F');
fragment G: ('g' | 'G');
fragment H: ('h' | 'H');
fragment I: ('i' | 'I');
fragment J: ('j' | 'J');
fragment K: ('k' | 'K');
fragment L: ('l' | 'L');
fragment M: ('m' | 'M');
fragment N: ('n' | 'N');
fragment O: ('o' | 'O');
fragment P: ('p' | 'P');
fragment Q: ('q' | 'Q');
fragment R: ('r' | 'R');
fragment S: ('s' | 'S');
fragment T: ('t' | 'T');
fragment U: ('u' | 'U');
fragment V: ('v' | 'V');
fragment W: ('w' | 'W');
fragment X: ('x' | 'X');
fragment Y: ('y' | 'Y');
fragment Z: ('z' | 'Z');
